package cn.jiedanba.cacert.common.ca.keypair;

import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import cn.jiedanba.cacert.common.bc.base.BaseSecurity;
import cn.jiedanba.cacert.common.ca.PkiUtil;

public class KeyPairUtil extends BaseSecurity {
	/**
	 * 生成密钥对
	 * 
	 * @param type
	 *            密钥类型 RSA，SM2，ECC
	 * @param keysize
	 *            密钥长度 RSA类型的秘钥传此参数
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidAlgorithmParameterException
	 */
	public static KeyPair generateKeyPair(String type, int keysize)
			throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
		Provider bc = new BouncyCastleProvider();
		KeyPair keyPair = null;
		if ("RSA".equals(type)) {
			KeyPairGenerator kpg = KeyPairGenerator.getInstance(type);
			kpg.initialize(keysize, new SecureRandom());
			keyPair = kpg.generateKeyPair();
			return keyPair;
		} else if ("SM2".equals(type)) {
			// 获取SM2椭圆曲线的参数
			final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
			// 获取一个椭圆曲线类型的密钥对生成器
			final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", bc);
			// 使用SM2的算法区域初始化密钥生成器
			kpg.initialize(sm2Spec, new SecureRandom());
			// 获取密钥对
			keyPair = kpg.generateKeyPair();
		} else if ("ECC".equals(type)) {
			ECGenParameterSpec ecSpec = new ECGenParameterSpec("prime256v1");
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", bc);
			keyPairGenerator.initialize(ecSpec, new SecureRandom());
			keyPair = keyPairGenerator.generateKeyPair();
		} else {
			throw new NoSuchAlgorithmException("密钥类型错误");
		}
		return keyPair;

	}

	public static void main1(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
		KeyPair key = generateKeyPair("RSA", 2048);

		byte[] p10 = PkiUtil.getPKCS10Certification("CN=Test", "SHA256WithRSA", key);
		System.out.println(Base64.encodeBase64String(p10));
		System.out.println(Base64.encodeBase64String(key.getPrivate().getEncoded()));
	}

	/**
	 * 签名
	 * 
	 * @param privateKey
	 *            私钥
	 * @param algorithm
	 *            签名算法
	 * @param data
	 *            签名内容
	 * @return
	 */
	public static String sign(PrivateKey privateKey, String algorithm, byte[] data) {
		try {
			PrivateKey priKey = privateKey;
			Signature signature = Signature.getInstance(algorithm, BC);
			signature.initSign(priKey);
			signature.update(data);
			byte[] signed = signature.sign();
			return Base64.encodeBase64String(signed);
		} catch (Exception e) {
			throw new RuntimeException("RSA签名异常！", e);
		}
	}

	public static void main(String[] args) {
		String pk = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIr1Ja9pPJPfm/h59OuX7SNDJJ7K2uUnXliXzUDme/wOGvyUfOR8MXIaq97sWismHr5puskJjdv08QcyqscNGsTqZTWHOUA+TiZugz3ZTGBDfFcLBimU1+MrECNUWfvRIMY4PomOkEOv4d3Rh6xeLKaDic1Kpz8CMbKihROf/ZdWrPKZx40+yVeRLrYA5sdcED1/0PqtDxxbANnJmdbWAEcsWBGnlBW2BSm+r0pxMt4mIqdazO+Lqdy+z/qaaWLHGNFicPbykPX0OiUakCMXMqomVGQ9IB5UIQUacVY6IbZT5k2lTgfvcjfYXMbbFE38+cyv8iKxg8cK6pHpdGnNjfAgMBAAECggEAVH9NQ7OSoicQIw6tiu4bcdI8YlffAQkDTvRGtNqj4F8MJ4GuVDJu+CxawcHpQQmupS7h2RTA6I0GczyqeRS/k7dB3NHfSDEjjBgcKMphO8bG3MEH41v8/ufFE9LuT8XB9alo/uRzKC7WlChliDwNs3+SZqY8Zrhzb5qegyTSjvJbLHOBaoFcwoKK4qoKrwSvpNyG9UQzc95rm0y7NjoY5D4gDLjk79Q3c1cr4LdsQ2BeBQNjP4vMOFTlJEO0r9jXaz49yUN4mbsAp23w5lbgKWE/sNk3QklCU/taKDmomR9uuaquw4Wq/hUPKxP8h9brwV9W41U6rzKEtYq0xB1rwQKBgQD+tNkaulEb9u9dctUtQaFNYpS7uKoLtTyq0VCmxFSkSV++jKkGv/pEBfrpCwtFk63e7T7Oj6QFND4DeFSpvGIhe5HQWf334a+uLn74zI7m1xiX46S9Zk3Ep92lUgA+zJwaxndyOfAWQ74cuLiwaIxHYbWY+f/G7glDxQhmdbBXUQKBgQDJtD0LSl6aVEnLGDKVYT0AaLmLIlC3W1saL7tiPe35CFOwEth8KmvJRVmF8wD5H9llVagMvKiYzLgcUiCsSkYK7r+ckm+r//O7WxWAPiwXBVEgSXinEKrft9oYCGnkm85kPBayDcY0NKwe1o7zgLn+ywCwhKUhIlgEmRgBli2BLwKBgBpAw7vohmGugx+LrYNbp2eViKUMtKI+TQGCT6DQzbSdR3wZfXaPpRkL0L/ifofuX9aBd57M2Wgb6WRsK7XPEAJJfU8PZ4j8PyJh8n5sfzI163gEY7+N4ugpMURP/mx6pIByAm/InwF8fATz2T19mS/mV1RsODvl3xiYH3SIHuPxAoGBALYLKzEefQWS30si2ryBl3ngCt3tKaZjGHUo8Vk4hahGgKmgSKy/6KouIh9H8+/kc+QGi/Z66zuFQQGmigCVxGOnmV5pt8on5sWI7n3hHw/j55VZWkCGRYJGv9sC9Pe0O3Gx3dXzopiJlXL7uOdCnhu9AjFOdm7SPVhhCA6eiRFXAoGBAIiYJrv3vM9QZ+pyLTVwtAbs5pNxu+cqCB1QZHispSF3uE8fZyk4zyv83NoqJijQEOJqKuX094kH4WOJkFTYM0Thsmu07p2ug2m6GQpr7YGg4cC4IV/3lLcLJ12yrpE9lR5UD0Jkbi8OZIQ8Qu5PNnbue9lfbYqeYlgbmc1z62KH";
		String hash = "MUswGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAvBgkqhkiG9w0BCQQxIgQgCbowOv0T5Vd+ux+7+ClY/z8+Bd7c7Mp8Kh7IUQbqb7Y=";
		System.out.println(
				sign(PkiUtil.getPrivateKey(Base64.decodeBase64(pk)), "SHA256WithRSA", Base64.decodeBase64(hash)));
	}

}
